package com.pelli.imarket.server.util;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.springframework.util.AntPathMatcher;

public class ResourceList {

	/**
	 * for all elements of java.class.path get a Collection of resources Pattern
	 * pattern = Pattern.compile(".*"); gets all resources
	 * 
	 * @param pattern
	 *            the pattern to match
	 * @return the resources in the order they are found
	 * @throws Exception 
	 */
	public static Collection<InputStream> getResources(final String pattern) throws Exception {
		final ArrayList<InputStream> retval = new ArrayList<InputStream>();
		final String classPath = System.getProperty("java.class.path", ".");
		final String[] classPathElements = classPath.split(":");
		for (final String element : classPathElements) {
			retval.addAll(getResources(element, pattern));
		}
		return retval;
	}

	private static Collection<InputStream> getResources(final String element,
			final String pattern) throws Exception {
		final ArrayList<InputStream> retval = new ArrayList<InputStream>();
		final File file = new File(element);
		if (file.isDirectory()) {
			retval.addAll(getResourcesFromDirectory(file, pattern));
		} else {
			retval.addAll(getResourcesFromJarFile(file, pattern));
		}
		return retval;
	}

	private static Collection<InputStream> getResourcesFromJarFile(final File file,
			final String pattern) throws Exception {
		final ArrayList<InputStream> retval = new ArrayList<InputStream>();
		ZipFile zf;
		try {
			zf = new ZipFile(file);
		} catch (final ZipException e) {
			throw new Error(e);
		} catch (final IOException e) {
			throw new Error(e);
		}
		final Enumeration e = zf.entries();
		while (e.hasMoreElements()) {
			final ZipEntry ze = (ZipEntry) e.nextElement();
			final InputStream fileName = zf.getInputStream(ze);
			final boolean accept = new AntPathMatcher().match(pattern,ze.getName());
//			System.out.println(ze.getName()+" --> "+fileName);
			if (accept) {
				retval.add(fileName);
			}
		}
		try {
			zf.close();
		} catch (final IOException e1) {
			throw new Error(e1);
		}
		return retval;
	}

	private static Collection<InputStream> getResourcesFromDirectory(
			final File directory, final String pattern) {
		final ArrayList<InputStream> retval = new ArrayList<InputStream>();
		final File[] fileList = directory.listFiles();
		for (final File file : fileList) {
			if (file.isDirectory()) {
				retval.addAll(getResourcesFromDirectory(file, pattern));
			} else {
				try {
					final InputStream is = new FileInputStream(file);
					final boolean accept = new AntPathMatcher().match(pattern, file.getName());
					System.out.println(file.getAbsolutePath()+"/"+pattern+" --> "+accept);
					if (accept) {
						retval.add(is);
					}
				} catch (final IOException e) {
					throw new Error(e);
				}
			}
		}
		return retval;
	}

	/**
	 * list the resources that match args[0]
	 * 
	 * @param args
	 *            args[0] is the pattern to match, or list all resources if
	 *            there are no args
	 */
//	public static void main(final String[] args) {
//		Pattern pattern;
//		if (args.length < 1) {
//			pattern = Pattern.compile(".*");
//		} else {
//			pattern = Pattern.compile(args[0]);
//		}
//		final Collection<String> list = ResourceList.getResources(pattern);
//		for (final String name : list) {
//			System.out.println(name);
//		}
//	}
}